package fem2.gui.pm.extr;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.TreeMap;

import math.FunctionRToR;
import fem2.Element;
import fem2.FieldInfo;
import fem2.Model;
import fem2.gui2.pm.HofemLinePlotDP;

public class ExtractorUtilities {

	public static Map<String, Extractor2D> getExtractors2D(Model model) {
		Map<String, Extractor2D> extractors = new TreeMap<String, Extractor2D>();

		if (model.countElements() > 0) {
			int d = model.countFields();
			Element element = model.getElement(0);

			if (element instanceof Element2D) {
				// primary results
				for (int i = 0; i < d; i++) {
					String name = FieldInfo.getFieldName(element.getFieldId(i));

					extractors.put(name, new PrimarySolutionExtractor2D(i));
				}

				// secondary results
				if (element instanceof Element2D) {
					for (Method method : element.getClass().getMethods()) {
						Class<?> returnType = method.getReturnType();
						Class<?>[] parameterTypes = method.getParameterTypes();

						if (returnType == double.class
								&& parameterTypes.length == 2
								&& parameterTypes[0] == double[].class
								&& parameterTypes[1] == double[][].class) {
							String name = method.getName().replace("get", "");

							extractors.put(name,
									new SecondarySolutionExtractorA2D(method));
						} else if (returnType == double.class
								&& parameterTypes.length == 1
								&& parameterTypes[0] == double[][].class) {
							String name = method.getName().replace("get", "");

							extractors.put(name,
									new SecondarySolutionExtractorB2D(method));
						}
					}
				}
			}
		}
		return extractors;
	}

	public static Map<String, Extractor1D> getExtractors1D(HofemLinePlotDP dp,
			Model model) {
		int d = model.countFields();
		Map<String, Extractor1D> extractors = new TreeMap<String, Extractor1D>();

		if (d > 0) {
			Element element = model.getElement(0);

			// secondary results
			if (element instanceof Element1D) {
				for (Method method : element.getClass().getMethods()) {
					Class<?> returnType = method.getReturnType();
					Class<?>[] parameterTypes = method.getParameterTypes();

					if (returnType == FunctionRToR.class
							&& parameterTypes.length == 0) {
						String name = method.getName().replace("get", "");

						extractors.put(name, new SecondarySolutionExtractorA1D(
								dp, method));
					}
					if (returnType == FunctionRToR.class
							&& parameterTypes.length == 1
							&& parameterTypes[0] == FunctionRToR.class) {
						String name = method.getName().replace("get", "");

						extractors.put(name, new SecondarySolutionExtractorB1D(
								dp, method));
					}
					if (returnType == FunctionRToR.class
							&& parameterTypes.length == 1
							&& parameterTypes[0] == FunctionRToR[].class) {
						String name = method.getName().replace("get", "");

						extractors.put(name, new SecondarySolutionExtractorC1D(
								dp, method));
					}
				}
			} else if (element instanceof Element2D
					&& model.getLineResults().countResultHolders() > 0) {

				for (String rn : model.getLineResults().getResultNames()) {
					extractors.put(rn, new SecondarySolutionExtractorD1D(rn));
				}
			}

			// primary results
			for (int i = 0; i < d; i++) {
				String name = FieldInfo.getFieldName(element.getFieldId(i));

				extractors.put(name, new PrimarySolutionExtractor1D(i));
			}
		}
		return extractors;
	}
}
